/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package administracion.helper;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.text.MessageFormat;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.border.MatteBorder;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 *
 * @author Luis_Angel
 */
public class MiTablePrint extends JFrame{
    protected int m_wPage;
  protected JScrollPane ps;
  protected int m_hPage;
  Printable m_target;
  JTable m_table;
  PageFormat pageFormat;
  int pageIndex = 0;
  BufferedImage[] bii;
  protected JComboBox m_cbScale;
  protected PreviewContainer m_preview;
  PrinterJob prnJob = PrinterJob.getPrinterJob();
  String judulx = "";

  public MiTablePrint(JTable ttarget) {
    this(ttarget, "Print Preview", "data table");
  }
  public MiTablePrint(JTable ttarget, String title, String judul) {
    super(title);
    this.judulx = judul;
    setSize(600, 400);
    setIconImage(new ImageIcon(super.getClass().getResource("/administracion/propiedades/logo.png")).getImage());
    this.m_table = ttarget;
    this.m_target = ttarget.getPrintable(JTable.PrintMode.NORMAL, new MessageFormat(this.judulx), new MessageFormat("Pagina {0}"));
    JToolBar tb = new JToolBar();
    JButton bt = new JButton("Imprimir");
    ActionListener lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        try {
          MiTablePrint.this.m_target = MiTablePrint.this.m_table.getPrintable(JTable.PrintMode.NORMAL, new MessageFormat(MiTablePrint.this.judulx), new MessageFormat("Pagina {0}"));
          MiTablePrint.this.prnJob.setPrintable(MiTablePrint.this.m_target);
          if (!MiTablePrint.this.prnJob.printDialog())
            return;
          MiTablePrint.this.setCursor(Cursor.getPredefinedCursor(3));

          MiTablePrint.this.prnJob.print();
          MiTablePrint.this.setCursor(Cursor.getPredefinedCursor(0));

          MiTablePrint.this.dispose();
        }
        catch (PrinterException ex) {
          ex.printStackTrace();
          System.err.println("Error de Impresion: " + ex.toString());
        }
      }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);

    tb.add(bt);
    bt = new JButton("Cerrar");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        MiTablePrint.this.dispose();
      }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);

    tb.add(bt);
    bt = new JButton("Configuracion de Pagina");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        MiTablePrint.this.m_target = MiTablePrint.this.m_table.getPrintable(JTable.PrintMode.NORMAL, new MessageFormat(MiTablePrint.this.judulx), new MessageFormat("Pagina {0}"));
        MiTablePrint.this.remove(MiTablePrint.this.ps);
        MiTablePrint.this.init(MiTablePrint.this.prnJob.pageDialog(MiTablePrint.this.prnJob.defaultPage()));
        MiTablePrint.this.validate();
        MiTablePrint.this.repaint();
        MiTablePrint.this.m_cbScale.setSelectedIndex(0);
      }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);
    tb.add(bt);
    bt = new JButton("PDF");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(null, "PDF");
      }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);
    tb.addSeparator();
    JLabel lb = new JLabel(new ImageIcon(super.getClass().getResource("/administracion/propiedades/Download_16x16.png")));
    lb.setText("Guardar Como");
    tb.add(lb);

    bt = new JButton("JPG");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JFileChooser jfc = new JFileChooser();
        jfc.setDialogType(1);
        int i = jfc.showDialog(null, "Save Image(JPG)");
        if (i == 1) return;
        for (int j = 0; j < MiTablePrint.this.pageIndex; ++j)
          MiTablePrint.this.simpanJPG(MiTablePrint.this.bii[j], jfc.getSelectedFile().getPath() + "" + String.valueOf(j) + ".jpg");
      }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);
    tb.add(bt);
    bt = new JButton("PNG");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JFileChooser jfc = new JFileChooser();
        jfc.setDialogType(1);
        int i = jfc.showDialog(null, "Save Image(PNG)");
        if (i == 1) return;
        for (int j = 0; j < MiTablePrint.this.pageIndex; ++j)
          MiTablePrint.this.simpanPNG(MiTablePrint.this.bii[j], jfc.getSelectedFile().getPath() + "" + String.valueOf(j) + ".png");
      }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);
    tb.add(bt);

    bt = new JButton("EXCEL");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JFileChooser jfc = new JFileChooser();
        jfc.setDialogType(1);
        int i = jfc.showDialog(null, "Guardar Excel(XLS)");
        if (i == 1) return;
      /*  for (int j = 0; j < MiTablePrint.this.pageIndex; ++j)
          
        MiTablePrint.this.simpanJPG(MiTablePrint.this.bii[j], jfc.getSelectedFile().getPath() + "" + String.valueOf(j) + ".jpg");*/
        ExcelTableExporter sd =   new ExcelTableExporter(m_table, new File(jfc.getSelectedFile().getPath() + ".xls"),"TabNombre",judulx);
        sd.export();
        }
    };
    bt.addActionListener(lst);
    bt.setAlignmentY(0.5F);
    tb.add(bt);


    String[] scales = { "10 %", "20 %", "30 %", "40 %", "50 %", "60 %", "70 %", "80 %", "90 %", "100 %", "125 %", "150 %", "200 %" };
    this.m_cbScale = new JComboBox(scales);
    lb = new JLabel(new ImageIcon(super.getClass().getResource("/administracion/propiedades/Preview_16x16.png")));
    lb.setText("Zooming");
    lst = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Thread runner = new Thread()
        {
          public void run() {
            String str = MiTablePrint.this.m_cbScale.getSelectedItem().toString();
            System.out.println("str " + str);
            if (str.endsWith("%"))
              str = str.substring(0, str.length() - 1);
            str = str.trim();
            int scale = 0;
            try { scale = Integer.parseInt(str); } catch (NumberFormatException ex) {
              return;
            }int w = MiTablePrint.this.m_wPage * scale / 100;
            int h = MiTablePrint.this.m_hPage * scale / 100;
            Component[] comps = MiTablePrint.this.m_preview.getComponents();
            for (int k = 0; k < comps.length; ++k) {
                //TODO modificacion !comps[k]
              if (comps[k] instanceof MiTablePrint.PagePreview){
                  //TODO modificacion continue .. dos lineas abajo fuera de if
                  MiTablePrint.PagePreview pp = (MiTablePrint.PagePreview)comps[k];
                  pp.setScaledSize(w, h);
              }
            }
            MiTablePrint.this.m_preview.doLayout();
            MiTablePrint.this.m_preview.getParent().getParent().validate();
          }
        };
        runner.start();
      }
    };
    this.m_cbScale.addActionListener(lst);
    this.m_cbScale.setMaximumSize(this.m_cbScale.getPreferredSize());
    this.m_cbScale.setEditable(false);
    tb.addSeparator();
    tb.add(lb);
    tb.add(this.m_cbScale);
    tb.addSeparator();
    tb.add(new aboutgw("Powered by LC, www.LombokCyber.com"));
    tb.validate();
    tb.repaint();
    getContentPane().add(tb, "North");
  }

  private void simpanJPG(BufferedImage bi, String filename) {
    try {
      ImageIO.write(bi, "jpeg", new File(filename)); } catch (Exception e) {
      System.out.println(e);
    }
  }

  private void simpanPNG(BufferedImage bi, String filename) {
    try {
      ImageIO.write(bi, "png", new File(filename)); } catch (Exception e) {
      System.out.println(e);
    }
  }
  public static void autoSizeTableColumns(JTable table) {
    table.setAutoResizeMode(0);
    TableColumnModel columns = table.getColumnModel();
    TableModel data = table.getModel();
    int margin = columns.getColumnMargin() * 2;
    int columnCount = columns.getColumnCount();
    int rowCount = data.getRowCount();
    for (int col = 0; col < columnCount; ++col) {
      TableColumn column = columns.getColumn(col);
      int modelCol = column.getModelIndex();
      int width = 0;
      for (int row = 0; row < rowCount; ++row) {
        TableCellRenderer r = table.getCellRenderer(row, col);
        int w = r.getTableCellRendererComponent(table, data.getValueAt(row, modelCol), false, false, row, col).getPreferredSize().width;

        if (w > width) {
          width = w;
        }
      }
      column.setPreferredWidth(width + margin);
    }
  }

  private void init(PageFormat format) {
    this.m_preview = new PreviewContainer();

    this.pageFormat = format;
    if ((this.pageFormat.getWidth() == 0.0D) || (this.pageFormat.getHeight() == 0.0D)) {
      System.err.println("Unable to determine default page size");
      return;
    }
    this.m_wPage = (int)this.pageFormat.getWidth();
    this.m_hPage = (int)this.pageFormat.getHeight();
    int scale = 10;
    int w = this.m_wPage * scale / 100;
    int h = this.m_hPage * scale / 100;

    this.bii = new BufferedImage[32];

    this.pageIndex = 0;
    try
    {
      while (true) {
        BufferedImage img = new BufferedImage(this.m_wPage, this.m_hPage, 1);

        Graphics g = img.getGraphics();
        g.setColor(Color.GRAY);
        g.fillRect(0, 0, this.m_wPage, 100);
        g.setColor(Color.white);
        g.drawString("Logo de la empresa", 15, 20);
        g.setColor(Color.white);
        g.fillRect(0, 60, this.m_wPage, this.m_hPage);
        if (this.m_target.print(g, this.pageFormat, this.pageIndex) != 0) {
          break;
        }
        PagePreview pp = new PagePreview(w, h, img);
        this.m_preview.add(pp);
        this.bii[this.pageIndex] = img;
        this.pageIndex += 1;
        //g.fillOval(-25, -25,50,60);
      }
    }
    catch (PrinterException e) {
      e.printStackTrace();
      System.err.println("Printing error: " + e.toString());
    }
    this.ps = new JScrollPane(this.m_preview);
    getContentPane().add(this.ps, "Center");
    setDefaultCloseOperation(2);
  }

  public void showPrintPreview()
  {
    init(this.prnJob.pageDialog(this.prnJob.defaultPage()));
    setLocationRelativeTo(null);
    setVisible(true);

  }

  class aboutgw extends JComponent implements MouseMotionListener, ActionListener, Runnable
  {
    int warna = 0;
    String theMessage;
    int messageX = 0; int messageY = 20;
    Color[] someColors = { Color.black, Color.red, Color.green, Color.blue, Color.magenta };
    boolean blinkState;

    public aboutgw(String message)
    {
      this.theMessage = message;
      addMouseMotionListener(this);
      Thread t = new Thread(this);
      t.start();
    }

    public void paintComponent(Graphics g)
    {
      g.setColor((this.blinkState) ? getBackground() : currentColor());
      g.drawString(this.theMessage, this.messageX, this.messageY);
    }

    public void mouseDragged(MouseEvent e) {
      this.messageX = e.getX();
      this.messageY = e.getY();
      repaint();
    }
    public void mouseMoved(MouseEvent e) {
    }

    private synchronized Color currentColor() {
      return this.someColors[this.warna];
    }

    public void run()
    {
      try {
        if (!this.blinkState) {
          this.warna += 1; if (this.warna == 5) this.warna = 0;
        }

        this.blinkState = (!this.blinkState);
        repaint();
        Thread.sleep(750L);
      }
      catch (InterruptedException ie)
      {
      }
    }

    public void actionPerformed(ActionEvent e)
    {
    }
  }

  class PagePreview extends JPanel
  {
    protected int m_w;
    protected int m_h;
    protected Image m_source;
    protected Image m_img;

    public PagePreview(int w, int h, Image source)
    {
      this.m_w = w;
      this.m_h = h;
      this.m_source = source;
      this.m_img = this.m_source.getScaledInstance(this.m_w, this.m_h, 4);

      this.m_img.flush();
      setBackground(Color.white);
      setBorder(new MatteBorder(1, 1, 2, 2, Color.black));
    }
    public void setScaledSize(int w, int h) {
      this.m_w = w;
      this.m_h = h;
      this.m_img = this.m_source.getScaledInstance(this.m_w, this.m_h, 4);

      repaint();
    }

    public Dimension getPreferredSize() {
      Insets ins = getInsets();
      return new Dimension(this.m_w + ins.left + ins.right, this.m_h + ins.top + ins.bottom);
    }

    public Dimension getMaximumSize()
    {
      return getPreferredSize();
    }

    public Dimension getMinimumSize() {
      return getPreferredSize();
    }

    public void paint(Graphics g) {
      g.setColor(getBackground());
      g.fillRect(0, 0, getWidth(), getHeight());
      g.drawImage(this.m_img, 0, 0, this);
      paintBorder(g);
    }
  }

  class PreviewContainer extends JPanel
  {
    protected int H_GAP;
    protected int V_GAP;

    PreviewContainer()
    {
      this.H_GAP = 16;
      this.V_GAP = 10;
    }
    public Dimension getPreferredSize() {
      int n = getComponentCount();
      if (n == 0)
        return new Dimension(this.H_GAP, this.V_GAP);
      Component comp = getComponent(0);
      Dimension dc = comp.getPreferredSize();
      int w = dc.width;
      int h = dc.height;
      Dimension dp = getParent().getSize();
      int nCol = Math.max((dp.width - this.H_GAP) / (w + this.H_GAP), 1);
      int nRow = n / nCol;
      if (nRow * nCol < n)
        ++nRow;
      int ww = nCol * (w + this.H_GAP) + this.H_GAP;
      int hh = nRow * (h + this.V_GAP) + this.V_GAP;
      Insets ins = getInsets();
      return new Dimension(ww + ins.left + ins.right, hh + ins.top + ins.bottom);
    }

    public Dimension getMaximumSize()
    {
      return getPreferredSize();
    }

    public Dimension getMinimumSize() {
      return getPreferredSize();
    }

    public void doLayout() {
      Insets ins = getInsets();
      int x = ins.left + this.H_GAP;
      int y = ins.top + this.V_GAP;
      int n = getComponentCount();
      if (n == 0)
        return;
      Component comp = getComponent(0);
      Dimension dc = comp.getPreferredSize();
      int w = dc.width;
      int h = dc.height;
      Dimension dp = getParent().getSize();
      int nCol = Math.max((dp.width - this.H_GAP) / (w + this.H_GAP), 1);
      int nRow = n / nCol;
      if (nRow * nCol < n)
        ++nRow;
      int index = 0;
      for (int k = 0; k < nRow; ++k) {
        for (int m = 0; m < nCol; ++m) {
          if (index >= n)
            return;
          comp = getComponent(index++);
          comp.setBounds(x, y, w, h);
          x += w + this.H_GAP;
        }
        y += h + this.V_GAP;
        x = ins.left + this.H_GAP;
      }
    }
  }

}
